package com.alongthink.javademo.utilTools;

import java.util.ArrayList;

/**
 * @Auther: along
 * @Date: 2019/4/8 14:15
 * @Description: 字节转换工具
 */
public class ConvertByte {

    /**
     * 转无符号
     *
     * @param s 转换值
     * @return 无符号
     */
    public static int toUnsigned(byte s) {
        return s & 0xFF;
    }

    public static int toUnsigned(short s) {
        return s & 0xFFFF;
    }

    /**
     * byte数组转换为无符号short整数
     *
     * @param bytes byte数组
     * @param changeHi 是否进行高低位转换，true低位在前高位在后，false高位在前低位在后
     * @return short整数
     */
    public static long bytesToUnsignedShort(byte[] bytes,boolean changeHi) {
        int t = 0;
        if(changeHi) {
            for (int i = bytes.length - 1; i >= 0; i--) {
                if(i == bytes.length - 1)
                    t = (bytes[i]&0xFF)<<(8*i);
                else
                    t = t|(bytes[i]&0xFF)<<(8*i);
            }
            return t;
        }
        else {
            for(int i=0;i<bytes.length;i++){
                if(i == 0)
                    t = (bytes[i]&0xFF);
                else
                    t = t|(bytes[i]&0xFF)<<(8*i);
            }
            return t;
        }
    }

    /**
     * byte数组转换为无符号short整数
     *
     * @param bytes byte数组
     * @param changeHi 是否进行高低位转换，true低位在前高位在后，false高位在前低位在后
     * @return short整数
     */
    public static int byte2ToUnsignedShort(byte[] bytes,boolean changeHi) {
        if(changeHi)
            return (bytes[1] << 8 & 0xFF00) | (bytes[0] & 0xFF);
        else
        {
            return (((bytes[0] & 0xFF)<<8)|(bytes[1] & 0xFF));
        }
    }

    /**
     * byte数组转换为无符号short整数
     *
     * @param bytes byte数组
     * @return short整数
     */
    public static int byte3ToUnsignedShort(byte[] bytes,boolean changeHi) {
        int b0 = bytes[0] & 0xFF;
        int b1 = bytes[1] & 0xFF;
        int b2 = bytes[2] & 0xFF;
        if(changeHi)
            return (b2 << 16) | (b1 << 8) | b0;
        else
            return (b0 << 16)|(b1 << 8) | b2;
    }

    /**
     * byte数组转换为无符号short整数
     *
     * @param bytes byte数组
     * @return short整数
     */
    public static long byte4ToUnsignedShort(byte[] bytes,boolean changeHi) {
        long b0 = bytes[0] & 0xFF;
        long b1 = bytes[1] & 0xFF;
        long b2 = bytes[2] & 0xFF;
        long b3 = bytes[3] & 0xFF;
        if(changeHi)
            return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
        else
            return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
    }

    /**
     * byte数组转换为无符号short整数
     *
     * @param bytes byte数组
     * @return short整数
     */
    public static long byte5ToUnsignedShort(byte[] bytes,boolean changeHi) {
        long b0 = bytes[0] & 0xFF;
        long b1 = bytes[1] & 0xFF;
        long b2 = bytes[2] & 0xFF;
        long b3 = bytes[3] & 0xFF;
        long b4 = bytes[4] & 0xFF;
        if(changeHi)
            return (b4 << 32) | (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
        else
            return (b0 << 32)|(b1<<24)|(b2<<16)|(b3<<8)|b4;
    }

    /**
     * byte数组转换为无符号short整数
     *
     * @param bytes byte数组
     * @return short整数
     */
    public static long byte8ToUnsignedShort(byte[] bytes,boolean changeHi) {
        long b0 = bytes[0] & 0xFF;
        long b1 = bytes[1] & 0xFF;
        long b2 = bytes[2] & 0xFF;
        long b3 = bytes[3] & 0xFF;
        long b4 = bytes[4] & 0xFF;
        long b5 = bytes[5] & 0xFF;
        long b6 = bytes[6] & 0xFF;
        long b7 = bytes[7] & 0xFF;
        if(changeHi)
            return (b7 << 56) | (b6 << 48) | (b5 << 40) | (b4 << 32) | (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
        else
            return (b0<<56)|(b1<<48)|(b2<<40)|(b3<<32)|(b4<<24)|(b5<<16)|(b6<<8)|b7;
    }

    /**
     * Convert byte[] to hex string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。
     *
     * @param src byte[] data
     * @return hex string
     */
    public static String bytesToHexString(byte[] src,char slicer) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
            if('\0'!=slicer)
                stringBuilder.append(slicer);
        }
        if('\0'!=slicer)
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
        return stringBuilder.toString();
    }


    /**
     * 将 10 进制转化为二进制
     *
     * @param de ：待转换的十进制
     * @return ：转换后的二进制（string）
     */
    public static String Decimal2Binary(long de,int byteNum) {
        StringBuilder numstr = new StringBuilder();
        while (de > 0) {
            long res = de % 2; //除2 取余数作为二进制数
            numstr.insert(0, res);
            de = de / 2;
        }
        int len = numstr.length();
        if(len<=byteNum*8){
            int cha = byteNum*8-len;
            for(int i=0;i<cha;i++){
                numstr.insert(0,0);
            }
        }
        return numstr.toString();
    }

    public static String Decimal2Oct(long str){
        return Long.toOctalString(str);
    }

    public static String Decimal2Hex(long str){
        return Long.toHexString(str);
    }

    /**
     * byte数组转成16进制的字符串
     *
     * @param bytes
     * @return
     */
    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
    public static String bytesToHexString(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static int string16ToInt(String hex,boolean changeHi){
        String temp = hex.replaceAll("^0[x|X]", "");
        int i = 0;
        if(changeHi){
            if(temp.length()==2){
                i=Integer.parseInt(temp, 16);
            }else if(temp.length()==4){
                temp = temp.substring(2,4)+temp.substring(0,2);
                i=Integer.parseInt(temp, 16);
            }else {
                i=Integer.parseInt(temp, 16);
            }
        }else {
            i=Integer.parseInt(temp, 16);
        }
        return i;
    }

    /**
     * 整形转字节数组
     *
     * @param iSource   源
     * @param iArrayLen 长度
     * @return 数组
     */

    public static byte[] intTobye(int iSource, int iArrayLen,boolean changeHi) {
        if(changeHi) {
            byte[] bLocalArr = new byte[iArrayLen];
            for (int i = 0; (i < iArrayLen); i++) {
                bLocalArr[i] = (byte) (iSource >> 8 * i & 0xFF);
            }
            return bLocalArr;
        }else {
            byte[] bLocalArr = new byte[iArrayLen];
            for (int i = iArrayLen-1; i >=0; i--) {
                bLocalArr[i] = (byte) ((iSource >> 8 * i) & 0xFF);
            }
            return bLocalArr;
        }
//        return bLocalArr;
    }

    public static byte[] longTobye(long iSource, int iArrayLen,boolean changeHi) {
        byte[] bLocalArr = new byte[iArrayLen];
        if(changeHi) {
            for (int i = 0; (i < 8) && (i < iArrayLen); i++) {
                bLocalArr[i] = (byte) (iSource >> 8 * i & 0xFF);
            }
        }else {
            for (int i = iArrayLen-1; i >=0; i--) {
                bLocalArr[i] = (byte) (iSource >> 8 * i & 0xFF);
            }
        }
        return bLocalArr;
    }

    /**
     * byte转无符号整型
     *
     * @param bytes 数组
     * @return 整型
     */
    public static int bytesToInt(byte[] bytes,boolean changeHi) {
        if(changeHi) {
            int i1 = bytes[0] & 0xff;
            int i2 = (bytes[1] & 0xff) << 8;
            int i3 = (bytes[2] & 0xff) << 16;
            int i4 = (bytes[3] & 0xff) << 24;
            return i1 | i2 | i3 | i4;
        }else {
            int i1 = (bytes[0] & 0xff) << 24;
            int i2 = (bytes[1] & 0xff) << 16;
            int i3 = (bytes[2] & 0xff) << 8;
            int i4 = (bytes[3] & 0xff);
            return i1 | i2 | i3 | i4;
        }
    }

    /**
     * 返回一段字节数组
     *
     * @param src   源
     * @param begin 开始
     * @param count 位数
     * @return 一段字节数组
     */
    public static byte[] SubBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        if (src.length > begin && src.length > count && src.length >= begin + count) {
            System.arraycopy(src, begin, bs, 0, count);
        }
        return bs;
    }

    /**
     * arraylist转byre[]
     *
     * @param arrayList arrayList
     * @return 转换后的byte[]
     */
    public static byte[] arrayListToByte(ArrayList arrayList) {
        byte[] byes = new byte[arrayList.size()];
        for (int i = 0; i < arrayList.size(); i++) {
            byes[i] = (byte) arrayList.get(i);
        }
        return byes;
    }


    public static double[] arrayListToDouble(ArrayList arrayList) {
        double[] byes = new double[arrayList.size()];
        for (int i = 0; i < arrayList.size(); i++) {
            byes[i] = (double) arrayList.get(i);
        }
        return byes;
    }

}
